package neuronvisualizer;

	/**
	 * Neuron Class
	 * @author John Newsom
	 * 
	 * This is the class that will hold all the data required
	 * to represent a neuron in the network. The network in the
	 * simulator will be a HashMap consisting of instances of 
	 * this class, all linked to their ID for easy referencing.
	 */


import java.util.ArrayList;
 
class Neuron{
	private int myID;
	private String myNeuronType;
	private int myXPos;
	private int myYPos;
	private int myZPos;
	private String myLayer;
	//private ArrayList<Connection> myConnections;
	private ArrayList<Integer> mySpikes;
	
	/**
	 * Default constructor, sets all properties to empty values
	 */
	public Neuron(){
		this.myID = -1;
		this.myNeuronType = "";
		this.myXPos = 0;
		this.myYPos = 0;
		this.myZPos = 0;
		this.myLayer = "";
		//this.myConnections = new ArrayList<Connection>();
		this.mySpikes = new ArrayList<Integer>();
	}
	
	/**
	 * Main constructor, includes all necessary values
	 */
	public Neuron(int ID,String type,String layer,int x,int y,int z){
		this.myID = ID;
		this.myNeuronType = type;
		this.myLayer = layer;
		this.myXPos = x;
		this.myYPos = y;
		this.myZPos = z;
		
		//this.myConnections = new ArrayList<Connection>();
		this.mySpikes = new ArrayList<Integer>();
	
	}
	
	/**
	 * Used to add a new connection to a neuron at run-time.
	 */
	//public void addConnection(Connection c){myConnections.add(c);}
	
	/**
	 * Remove a connection from a neuron at run-time.
	 */
	/*public void removeConnection(Connection c){
		for(int i=0;i<myConnections.size();i++){
			Connection tempConnect = (Connection)myConnections.get(i);
			if((tempConnect.head()==c.head())&&(tempConnect.tail()==c.tail())){
				try{
					myConnections.remove(i);
				}catch(Exception e){System.out.println(e.toString());}
			}
		}
	}*/
	/**
	 * Returns the size of the connection list
	 */
	//public int numberOfConnections(){return myConnections.size();}
	
	/**
	 * Change or retrieve the 3d coordinates of the neuron.
	 */
	public int X(){return myXPos;}
	public void X(int x){myXPos = x;}
	
	public int Y(){return myYPos;}
	public void Y(int y){myYPos = y;}
	
	public int Z(){return myZPos;}
	public void Z(int z){myZPos = z;}
	
	/**
	 * Change or retrieve the Neuron type
	 */
	public String type(){return myNeuronType;}
	public void type(String t){myNeuronType = t;}
	
	/**
	 * Change or retrieve the layer of the Neuron
	 */
	public String layer(){return myLayer;}
	public void layer(String l){myLayer = l;}
	
	/**
	 * Change or retrieve ID of the Neuron
	 */
	public int ID(){return myID;}
	public void ID(int id){myID = id;}
	
	
	/**
	 * Add a spike to the list of this neuron's spikes.
	 * There is no reason to remove spikes however.
	 */
	public void spike(Integer time){mySpikes.add(time);}
	/**
	 * Return the spike count of this neuron
	 */
	public int numberOfSpikes(){return mySpikes.size();}
	 
	
	/**
	 * Return the average time between spikes 
	 */
	public double averageBetweenSpikes(){
		double result=0.0;
		if(mySpikes.size()==0){
			result = 0;
			//If there's no spikes, there's no average time. 
		}
		else if(mySpikes.size()==1){
			result = (Integer)mySpikes.get(0); 
			//If there's only one spike, the average is how long before that spike.
		}
		else{
			//Add the time between each spike to get a total
			//and divide by the number of spikes
			for(int i=1;i<mySpikes.size();i++){
				result += ((Integer)mySpikes.get(i)) - ((Integer)mySpikes.get(i-1));
			}
			result = (result * 1.0) / mySpikes.size();
		}
		return result;
	}
	
}//END CLASS NEURON